"""
Соединение с MySQL сервером.
"""

import os
import sys
import configparser

from PyQt5.QtSql import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


def get_db_mysql(ini_file):

    # ОТКРЫТЬ БД на сервере MySQL
    
    """ Все INI файлы создаются в каталоге APPDATA. Создаем переменную парсера 
    ini файла. Читаем ini файл. Если секции SERVER нет, то создаём."""
    ini_file = "{}\\{}".format(os.getenv('APPDATA'), ini_file)
    config = configparser.ConfigParser()
    config.read(ini_file)
    if not ('SERVER' in config):
        config['SERVER'] = {}

    """ Создаём соединение. Открываем БД. Если удачно возвращаем ссылку на 
    соединение с БД."""
    conn = QSqlDatabase.addDatabase("QMYSQL")              
    data_base = open_db(conn, config)
    if data_base:
        return data_base
    """ Если соединение не удалось, то открываем диалог для ввода параметров."""
    dialog = DialogServer(conn, config)
    result = dialog.exec_()
    """ Если в диалоге удалось"""
    if result == QDialog.Accepted:
        with open(ini_file, 'w') as file_ini:
            config.write(file_ini)
        return dialog.data_base
    else:
        QSqlDatabase.close()
        
def open_db(conn, config):

    # ОТКРЫТЬ БД
    
    """ Подставляем параметры БД из секции SERVER в параметры соединения."""
    server = config['SERVER']
    conn.setHostName(server.get('host_name'))
    conn.setDatabaseName(server.get('data_base'))
    conn.setUserName(server.get('user'))
    conn.setPassword(server.get('password'))
    """Если база открылась, возвращаем ссылку на соединение, иначе выводим 
    сообщение об ошибке."""
    if conn.open():                                                               
        return conn
    else:
        error = conn.lastError()
        num_error = error.number()
        if num_error == 1044:
            message = ("Введите правильное имя базы данных. "
                "Обратитесь за помощью к системному администратору.")
        elif num_error == 1045:
            message = ("Введите правильное имя пользователя и пароль. "
                "Обратитесь за помощью к системному администратору.")
        elif num_error in (2003, 2005):
            message = ("Введите правильное сетевое имя сервера или IP адрес. "
                "Обратитесь за помощью к системному администратору.")
        else:
            message = ("Код ошибки сервера: {}. Оригинальное сообщение: {}. "
                "Обратитесь за помощью к программисту."
                .format(num_error, error.text()))
        report = QMessageBox()
        report.setIcon(QMessageBox.Error) # иконка
        report.setWindowTitle("НЕТ СОЕДИНЕНИЯ С БАЗОЙ ДАННЫХ")
        report.setText(message)
        report.setWindowIcon(QIcon("pict\\order.ico"))
        report.exec_()


class DialogServer(QDialog):
    """
    Форма ручного соединения с сервером.
    Вход: параметры соединения.
    """

    def __init__(self, conn, config):
        super().__init__()

        self.conn = conn
        self.config = config
        self.initUI()
    
    def initUI(self):

        # СОЗДАНИЕ ИНТЕРФЕЙСА

        """ Создаем поля и обновременно грузим в них параметры из конфига."""
        server = self.config['SERVER']
        self.edt_host_name = QLineEdit(server.get('host_name',''))
        self.edt_database = QLineEdit(server.get('data_base',''))
        self.edt_user_name = QLineEdit(server.get('user',''))
        self.edt_password = QLineEdit(server.get('password',''))
        btn_open_db = QPushButton('ОТКРЫТЬ БАЗУ ДАННЫХ')
        btn_open_db.clicked.connect(self.btn_open_db_click)
        """ Сбрасываем всё на форму."""
        form = QFormLayout()
        form.addRow("Сервер", self.edt_host_name)
        form.addRow("База", self.edt_database)
        form.addRow("Логин", self.edt_user_name)
        form.addRow("Пароль", self.edt_password)
        form.addRow(btn_open_db)
        self.setLayout(form)
        self.setWindowTitle("ПАРАМЕТРЫ БД")
        self.setMinimumWidth(200)

    def btn_open_db_click(self):
    
        """ Проверка заполнения полей. """
        if (not self.edt_host_name.text() or                                    
            not self.edt_database.text() or
            not self.edt_user_name.text() or
            not self.edt_password.text()):
            report = QMessageBox()
            report.setIcon(QMessageBox.Error) # иконка
            report.setWindowTitle("НЕДОСТАТОЧНО ИНФОРМАЦИИ")
            report.setText("Все поля должны быть заполнены.")
            report.setWindowIcon(QIcon("pict\\order.ico"))
            report.exec_()
            return
            
        """Загрузка значений полей в переменную конфигурации.""" 
        server = self.config['SERVER']                                          
        server['host_name'] = self.edt_host_name.text()                        
        server['data_base'] = self.edt_database.text()
        server['user'] = self.edt_user_name.text()
        server['password'] = self.edt_password.text()
            
        """ Соединяемся с БД. Если удалось, сохраняем ссылку для последующего
        чтения."""
        data_base = open_db(self.conn, self.config)
        if data_base:
            self.data_base = data_base
            self.accept()

    def closeEvent(self,е):
        self.reject()

x = 1234

if __name__ == '__main__':
    app = QApplication(sys.argv)
    db = data_base_mysql("connn.ini")
    if db:
        print("OK")
